namespace BM.Tools.WebControls.MForm.Navigation.XPath
{
    using System;

    using BM.Tools.WebControls.MForm.Navigation.XPath.NodeTests;

    /// <summary>
    /// A definition of the xpath node test
    /// </summary>
    public abstract class NodeTest
    {
        /// <summary>
        /// Gets the text representation of the node test.
        /// </summary>
        /// <value>
        /// The text in which the node test can be represented in xpath.
        /// </value>
        public abstract string Text
        {
            get;
        }

        /// <summary>
        /// Creates an appropriate node test object based on its string representation
        /// </summary>
        /// <param name="nodeTestText">
        /// The node test text.
        /// </param>
        /// <returns>
        /// a <see cref="NodeTest" /> object
        /// </returns>
        public static NodeTest Create(string nodeTestText)
        {
            if (String.IsNullOrEmpty(nodeTestText))
            {
                return new DescendantOrSelfTest();
            }

            if (nodeTestText.EndsWith(":*", StringComparison.Ordinal))
            {
                return new AllInNamespaceTest(nodeTestText.Substring(0, nodeTestText.Length - 2));
            }

            if (nodeTestText.StartsWith("*:", StringComparison.Ordinal))
            {
                return new AllWithLocalNameTest(nodeTestText.Substring(2));
            }

            if (nodeTestText.Equals("*", StringComparison.Ordinal))
            {
                return new AllTest();
            }

            if (nodeTestText.Equals(".", StringComparison.Ordinal))
            {
                return new SelfTest();
            }

            if (nodeTestText.Equals("..", StringComparison.Ordinal))
            {
                return new ParentTest();
            }

            if (nodeTestText.Equals("@*", StringComparison.Ordinal))
            {
                return new AllAttributeTest();
            }

            if (nodeTestText.StartsWith("@", StringComparison.Ordinal))
            {
                return new AttributeTest(nodeTestText.Substring(1));
            }
            
            return new ElementTest(nodeTestText);            
        }
    }
}